package org.hzero.interfaces.common.helper.impl;

import org.hzero.interfaces.common.entity.KnifeInterfaceLogRecord;
import org.hzero.interfaces.common.helper.KnifeInterfaceLogHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;

import java.lang.reflect.Method;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;

/**
 * 2020-07-02
 * 本类适用于hpms内部使用RestTemplate去请求第三方系统记录日志,该类进行了适配post和exchange方法,如果有使用其他方式,但没有记录下日志,则需要调整此类中的构造日志规则
 *
 * @author: tianhao.luo@hand-china.com 2021/7/1  下午12:02
 */
public class KnifeRestTemplateInterfaceLogHelperImpl extends KnifeInterfaceLogHelper {
    private static final Logger LOGGER = LoggerFactory.getLogger(KnifeRestTemplateInterfaceLogHelperImpl.class);
    private volatile int index = -1;


    public KnifeRestTemplateInterfaceLogHelperImpl(KnifeInterfaceLogRecord knifeInterfaceLogRecord) {
        super(knifeInterfaceLogRecord);
    }

    public KnifeRestTemplateInterfaceLogHelperImpl(KnifeInterfaceLogRecord knifeInterfaceLogRecord, Exception exception) {
        super(knifeInterfaceLogRecord, exception);
    }

    /**
     * 预处理
     *
     * @param method 方法
     */
    @Override
    public void preDeal(Method method) throws UnknownHostException {
        super.preDeal(method);
        // 记录请求RequestBody请求体
        if (method.getName().matches("^post[A-Za-z0-9]+")) {
            index = 1;
            // 记录请求为post
            knifeInterfaceLogRecord.setInterfaceRequestMethod(HttpMethod.POST.name());
        } else {
            // 给一个默认值;也可能buildInterfaceLogRequest在中替换
            knifeInterfaceLogRecord.setInterfaceRequestMethod(HttpMethod.GET.name());
        }
    }

    @Override
    public void buildInterfaceLogResponse(Object responseObj, Class<?>... ignoreClassArray) {
        super.buildInterfaceLogResponse(responseObj, ignoreClassArray);
        if (responseObj != null) {
            ResponseEntity<?> responseEntity = (ResponseEntity<?>) responseObj;
            // 1.更新状态
            HttpStatus statusCode = responseEntity.getStatusCode();
            knifeInterfaceLogRecord.setInterfaceResponseCode(String.valueOf(statusCode.value()));
            knifeInterfaceLogRecord.setInterfaceResponseStatus(statusCode.getReasonPhrase());
        }
    }


    @Override
    public void buildInterfaceLogRequest(Object[] args, Class<?>... ignoreClassArray) {
        for (int i = 0; i < args.length; i++) {
            // post的RequestBody参数放后面处理
            if (index != i && !argIsIgnore(args[i].getClass(), ignoreClassArray)) {
                Object arg = args[i];
                if (arg instanceof String) {
                    knifeInterfaceLogRecord.setInterfaceUrl((String) arg);
                }
                if (arg instanceof URI) {
                    knifeInterfaceLogRecord.setInterfaceUrl(((URI) arg).getPath());
                }
                if (arg instanceof HttpMethod) {
                    knifeInterfaceLogRecord.setInterfaceRequestMethod(arg.toString());
                }
                if (arg instanceof HttpEntity) {
                    // 处理请求体
                    Object body = ((HttpEntity<?>) arg).getBody();
                    super.setRequestBodyContentOrFileId(body);
                    // 处理请求头
                    HttpHeaders headers = ((HttpEntity<?>) arg).getHeaders();
                    super.setRequestHeaderOrFileId(headers);
                    List<String> userAgentList = headers.get(HttpHeaders.USER_AGENT);
                    knifeInterfaceLogRecord.setUserAgent(userAgentList != null ? userAgentList.get(0) : null);
                }
                if (arg instanceof Object[] || arg instanceof Map) {
                    // 处理请求参数
                    super.setRequestUrlContentOrFileId(arg);
                }
            }
        }
        // 最后处理post参数RequestBody
        if (index != -1) {
            Object requestBodyObj = args[index];
            super.setRequestBodyContentOrFileId(requestBodyObj);
        }
    }

    @Override
    public void buildInterfaceLogRequest(Map<String, Object> map, Class<?>... ignoreClassArray) {

    }
}
